#export PYTHONPATH=$HOME/dev/bcat/src in bash
import abc


#########  Global Interface  ########################
 
class BizError(Exception);
    def __init__(self, code, msg):
        pass

class Request(object):
    pass
class Response(object):
    pass

class Meta(object):
    def __init__(self):
        self.__pairs = {}

    def value(self, key):
        return self.__pairs.get(key)

    def set_value(self, key, value):
        self.__pairs(key) = value
        return self

class Service(object):
    def __init__(self):
        self.__meta = {}

    def meta(self):
        return self.__meta
    def set_meta(self, meta):
        self.__meta = meta

    @abc.abstractmethod
    def run(self, request) -> Response:
        pass



####### Global Resource  ################

# has default, also can update the value
class Databases(object):
    def __init__(self):
        pass
    #.....

# has default 
class Fronts(object):
    def __init__(self):
        pass
    #....

class Backends(object):
    def __init__(self):
        pass
    #....


######### Biz Layer Service ##############

class BizService(Service):
    def __init__(self):
        super().__init__()
        self.__dbs = Databases.instance()
        self.__fronts = Fronts.instance()
        self.__backends = Backends.instance()

    def __del__(self):
        self.__backends = None
        self.__fronts = None
        self.__dbs = None
        

    def dbs(self):
        return self.__dbs
    def fronts(self):
        return self.__fronts
    def backends(self):
        return self.__backends

    def _biz(self, request, ctx) -> Response:
        raise NotImplementedError()

    def run(self, request, ctx) -> Response:
        try
            return self._biz(request)
        except BizError as e:
            return BizError.to_respone()
        except Exception as e:
            pass


####  biz::login ###########################

def LoginService(BizService):
    def db(self):
        return self.dbs().default()

    def front(self):
        return  self.fronts().get(self.__user.id);
    def backend(self):
        return self.backends().get(self.__user.id)

    def dbo_user(self):
        return User.from_db(self.db())

    def _biz(self, request, ctx) -> Response:
        user = User.from_request(request)
        self.user_check()

        d_user = self.dbo_user()

        self.password_check()

        session = self.front()

        self.backend().send(user)

        return self.to_reponse()
    #end def run





####  grpc::service ###########################
class LoginService(object):
    def from_input(user: User):
        return Request(user)
    def to_result(resp: Response):
        return UserRespone(resp)

    def call(self, user: User):
        try: 
            request = from_input(user)
            resp = LoginService(ctx).run(request)
            return to_result(resp)
        except: RPCError as e:
            pass
        except Exception as e:
            logging.error(f"{e}");
    #end def
#end class
            


#TODO: safe inceptor
class SafeService(object):
    pass


class App(object):
    def __init__(self):
        pass
    def __del__(self):
        pass
    def run(self): 
        server = Server.Builder()
            .port(1234)
            .add_service(LoginService())
            .add_Service(Service2())
            .run()
    
App().run()

